package com.momo.seckilling.control;

import com.momo.seckilling.EventModel.CentralEventProcessor;
import com.momo.seckilling.EventModel.Event;
import com.momo.seckilling.EventModel.SeckillEvent;
import com.momo.seckilling.EventModel.SeckillEventType;
import com.momo.seckilling.entity.ProductInfo;
import com.momo.seckilling.entity.SeckillProductInfo;
import com.momo.seckilling.form.SeckillForm;
import com.momo.seckilling.service.*;
import com.momo.seckilling.strategy.ProcedureLockBy;
import com.momo.seckilling.strategy.SeckillIntegrByDistrAndFuture;
import com.momo.seckilling.strategy.SeckillOperator;
import com.momo.seckilling.utils.RedisLockUtil;
import com.momo.seckilling.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * Created by li on 2019/2/2.
 */
@Controller
@RequestMapping("seckKillProductControl")
public class SeckKillProductControl implements InitializingBean {

//    @Autowired
//    ProductService productService;

    @Autowired
    SeckillProductService seckillProductService;

    @Autowired
    SeckillIntegrationByService seckillIntegrationByService;
    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    SeckillByService seckillByService;

    private SeckillOperator seckillOperator;

    private CentralEventProcessor centralEventProcessor;

    public SeckKillProductControl() {
        String strategy = RedisLockUtil.get("seckillStrategy");
        if (StringUtils.isBlank(strategy)) {
            seckillOperator = new SeckillIntegrByDistrAndFuture(seckillIntegrationByService);
        } else {
            if ("ProcedureLockBy".equals(strategy)) {
                seckillOperator = new ProcedureLockBy(seckillByService);
            } else if ("SeckillIntegrByDistrAndFuture".equals(strategy)) {
                seckillOperator = new SeckillIntegrByDistrAndFuture(seckillIntegrationByService);
            }
        }
    }

    @RequestMapping(value = "listShopProduct", method = RequestMethod.GET)
    public String listShopProduct(int shopId, Model model) {
        List<ProductInfo> list = productInfoService.listProductInfo(shopId);
        model.addAttribute("list", list);
        return "listproduct";
    }

    @RequestMapping(value = "preSaveSeckillProduct", method = RequestMethod.GET)
    public String preSaveSeckillProduct(int id, Model model) {
        ProductInfo productInfo = productInfoService.findProductById(id);
        model.addAttribute("productInfo", productInfo);
        return "preSaveSeckill";
    }

    @RequestMapping(value = "saveSeckillProduct", method = RequestMethod.POST)
    public String saveSeckillProduct(SeckillForm seckillForm, Model model) {
        seckillProductService.saveSeckillProduct(seckillForm);
        return "seckillSaveSuccess";
    }

    @RequestMapping(value = "listSeckillProductAll", method = RequestMethod.GET)
    public String listSeckillProductAll(int shopid, Model model) {
        SeckillForm seckillForm = new SeckillForm();
        seckillForm.setShopid(shopid);
        List<SeckillProductInfo> list = seckillProductService.listSeckillInfo(seckillForm);
        model.addAttribute("list", list);
        return "listSeckillProductInfo";
    }

    @RequestMapping(value = "updateState", method = RequestMethod.GET)
    public String updateState(int id, int state, Model model) {
        seckillProductService.updateSeckillInfoState(id, state);
        return "seckillUpdateSuccess";
    }

    @RequestMapping(value = "listSeckillProductByState", method = RequestMethod.GET)
    public String listSeckillProductByState(Model model) {
        SeckillForm seckillForm = new SeckillForm();
        seckillForm.setState(3);
        List<SeckillProductInfo> list = seckillProductService.listSeckillInfo(seckillForm);
        model.addAttribute("list", list);
        return "seckillPortal";
    }

    @RequestMapping(value = "seckillProduct", method = RequestMethod.GET)
    public String seckillProduct(int userid, int id, Model model) {
        Event seckillEvent = new SeckillEvent("new", SeckillEventType.NEW, seckillOperator, userid, id);
        centralEventProcessor.processEvent(seckillEvent);
        return "seckillSuccess";
    }

    @RequestMapping(value = "setSeckillStrategy", method = RequestMethod.GET)
    public String setSeckillStrategy(String strategy) {

        if ("ProcedureLockBy".equals(strategy)) {
            seckillOperator = new ProcedureLockBy(seckillByService);
        } else if ("SeckillIntegrByDistrAndFuture".equals(strategy)) {
            seckillOperator = new SeckillIntegrByDistrAndFuture(seckillIntegrationByService);
        }
        RedisLockUtil.set("seckillStrategy", strategy);

        return "setSeckillStrategySuccess";
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        centralEventProcessor = new CentralEventProcessor();
        String strategy = RedisLockUtil.get("seckillStrategy");
        if (StringUtils.isBlank(strategy)) {
            seckillOperator = new SeckillIntegrByDistrAndFuture(seckillIntegrationByService);
        } else {
            if ("ProcedureLockBy".equals(strategy)) {
                seckillOperator = new ProcedureLockBy(seckillByService);
            } else if ("SeckillIntegrByDistrAndFuture".equals(strategy)) {
                seckillOperator = new SeckillIntegrByDistrAndFuture(seckillIntegrationByService);
            }
        }
    }
}
